package com.base.cn.platform.os.service.order.callback;

import com.base.cn.platform.os.common.md5.MD5;
import com.base.cn.platform.os.common.msg.WXTmpEnum;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.action.ActionKey;
import com.base.cn.platform.os.common.utils.course.CourseType;
import com.base.cn.platform.os.common.utils.order.OrderStatus;
import com.base.cn.platform.os.common.utils.order.PayType;
import com.base.cn.platform.os.common.utils.order.ShopType;
import com.base.cn.platform.os.common.utils.user.AccountBizType;
import com.base.cn.platform.os.common.utils.user.AccountHistoryType;
import com.base.cn.platform.os.common.utils.user.AccountType;
import com.base.cn.platform.os.entity.course.cou.Course;
import com.base.cn.platform.os.entity.order.order.Order;
import com.base.cn.platform.os.entity.order.order.OrderDetails;
import com.base.cn.platform.os.entity.order.order.OrderType;
import com.base.cn.platform.os.entity.user.account.CusUserAccount;
import com.base.cn.platform.os.service.course.agent.income.AgentIncomeInfoService;
import com.base.cn.platform.os.service.course.agent.user.AgentUserService;
import com.base.cn.platform.os.service.course.book.BookService;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyPackageCourseService;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyRecordService;
import com.base.cn.platform.os.service.course.qa.qaattend.QaAttendService;
import com.base.cn.platform.os.service.course.qa.record.QaBuyRecordService;
import com.base.cn.platform.os.service.exam.record.ExamBuyRecordService;
import com.base.cn.platform.os.service.op.activity.OpActivityBiz;
import com.base.cn.platform.os.service.op.affiche.tmp.SendMessage;
import com.base.cn.platform.os.service.op.coupon.OpCouponCodeBiz;
import com.base.cn.platform.os.service.order.order.OrderBiz;
import com.base.cn.platform.os.service.user.account.CusUserAccountBiz;
import com.base.cn.platform.os.service.user.integral.CusUserIntegralBiz;
import com.base.cn.platform.os.service.user.member.CusUserMemberBuyRecordBiz;
import com.base.cn.platform.os.service.user.user.CusUserBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 支付成功回调处理
 *
 * @author s.li
 * @create 2018-05-10-19:08
 */
@Service
public class SuccessCallbackHandle {
    @Autowired
    private CourseBuyRecordService courseBuyRecordService;
    @Autowired
    private ExamBuyRecordService examBuyRecordService;
    @Autowired
    private CusUserMemberBuyRecordBiz cusUserMemberBuyRecordBiz;
    @Autowired
    private QaBuyRecordService qaBuyRecordService;
    @Autowired
    private QaAttendService qaAttendService;
    @Autowired
    private CusUserAccountBiz cusUserAccountBiz;
    @Autowired
    private OrderBiz orderBiz;
    @Autowired
    private CourseBuyPackageCourseService courseBuyPackageCourseService;
    @Autowired
    private CusUserIntegralBiz cusUserIntegralBiz;
    @Autowired
    private OpCouponCodeBiz opCouponCodeBiz;
    @Autowired
    private CusUserBiz cusUserBiz;
    @Autowired
    private AgentIncomeInfoService agentIncomeInfoService;
    @Autowired
    private AgentUserService agentUserService;
    @Autowired
    private OpActivityBiz opActivityBiz;
    @Autowired
    private SendMessage sendMessage;
    @Autowired
    private BookService bookService;

    /**
     * 处理支付成功的后期处理
     * @param order 订单对象（包含订单所有数据）
     */
    public void handleSuccess(Order order) throws Exception{
        order = orderBiz.setOrderExData(order,false,true,true,false);
        handleSuccess(order,new BigDecimal(0));
    }

    /**
     * 处理支付成功的后期处理
     * @param order 订单对象（包含订单所有数据）
     * @param sysUserId 管理员ID
     */
    @Transactional(rollbackFor = IllegalArgumentException.class)
    public void handleSuccess(Order order, BigDecimal sysUserId) throws Exception{
        //订单的所有流水记录数据
        List<OrderDetails> orderDetailsList = order.getOrderDetailsList();
        //通过商品类型分组
        Map<String,List<OrderDetails>> orderDetailsListMaps = orderDetailsList.stream().collect(Collectors.groupingBy(e->e.getShopType()));
        //自动激活套餐流水记录列表
        List<String> keyList = new ArrayList<>(orderDetailsListMaps.keySet());
        //课程专业
        List<String> courseSubjectIds = new LinkedList<>();
        for(String k : keyList){
            List<OrderDetails> v = orderDetailsListMaps.get(k);
            if(k.equals(ShopType.ORDER_SHOP_COURSE)){//课程
                List<OrderDetails> packageDetailsList = new ArrayList<>();
                List<Map<String,Object>> courseBuyRecordList = new ArrayList<>();
                v.forEach(details -> {
                    Map<String,Object> record = new HashMap<>();
                    record.put("orderId",order.getId());
                    record.put("orderNo",order.getOrderNo());
                    record.put("detailsId",details.getId());
                    record.put("payType",order.getPayType());
                    record.put("price",details.getRealPrice());
                    record.put("userId",order.getUserId());
                    record.put("courseId",details.getShopId());
                    record.put("validType",details.getValidType());
                    record.put("validDay",details.getValidDay());
                    record.put("validTime",details.getValidTime());
                    record.put("courseTypeKey",details.getCourseType());
                    record.put("courseStatus",order.getOrderStatus());
                    //默认全部是激活状态，套餐课程在记录执行添加前自行判断是否是自动激活，
                    // 如果不是自动激活请把在运行前的地方把激活状态设置为0
                    record.put("status",1);
                    Course course = details.getShop().getCourse();
                    //获取自动激活的套餐课程
                    if(course.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())){
                        int courseNum = course.getCourseNum();
                        int useNum = course.getUseNum();
                        //可自动激活条件
                        if(courseNum==useNum || useNum==0){//自动激活
                            packageDetailsList.add(details);
                        }else{//需要手动激活
                            record.put("status",0);
                        }
                    }
                    String subjectIds = course.getSubjectIds();
                    if(StringUtils.isNotEmpty(subjectIds)){
                        courseSubjectIds.add(subjectIds);
                    }
                    courseBuyRecordList.add(record);
                });
                courseBuyRecordService.createCourseBuyRecord(courseBuyRecordList);
                Double coursePrice = v.stream().mapToDouble(OrderDetails::getPrice).sum();
                if(order.getRealPrice()>0 && coursePrice.doubleValue() > 0){
                    //是否购买过付费课程
                    cusUserBiz.updateUserBuyCourse(order.getUserId());
                }

                //如果有自动激活套餐数据列表
                if(ObjectUtils.isNotEmpty(packageDetailsList)){
                    String packageIds = packageDetailsList.stream().map(e->e.getShopId().toString()).collect(Collectors.joining(","));
                    //生成激活记录
                    courseBuyPackageCourseService.autoActivation(order.getId(),order.getOrderNo(),packageIds,order.getUserId());
                }
                //获取课程的总金额
                Double sumScore = v.stream().mapToDouble(OrderDetails::getRealPrice).sum();
                //添加积分、经验
                cusUserIntegralBiz.addUserIntegralData(ActionKey.PAYSUCCESS,order.getUserId(),BigDecimal.ZERO,0,2);
            }
            if(k.equals(ShopType.ORDER_SHOP_MEMBER)){//生成会员记录
                int validDay = 0;
                for(OrderDetails details : v){
                    if(ObjectUtils.isNotEmpty(details.getValidDay())){
                        validDay += details.getValidDay();
                    }
                }
                cusUserMemberBuyRecordBiz.addUserMemberBuyRecord(order.getUserId(),validDay);
            }
            if(k.equals(ShopType.ORDER_SHOP_EXAM)){//试卷
                List<Map<String,Object>> examBuyRecordList = new ArrayList<>();
                v.forEach(details -> {
                    Map<String,Object> record = new HashMap<>();
                    record.put("userId",order.getUserId());
                    record.put("examId",details.getShopId());
                    record.put("orderId",order.getId());
                    record.put("orderNo",order.getOrderNo());
                    record.put("detailsId",details.getId());
                    record.put("payType",order.getPayType());
                    //获取使用次数
                    Integer answerNum = details.getShop().getExam().getAnswerNum();
                    record.put("answerNum",answerNum);
                    examBuyRecordList.add(record);
                });
                examBuyRecordService.createExamBuyRecord(examBuyRecordList);
            }
            if(k.equals(ShopType.ORDER_SHOP_QA)){//问答
                List<Map<String,Object>> qaBuyRecordList = new ArrayList<>();
                v.forEach(details -> {
                    Map<String,Object> record = new HashMap<>();
                    record.put("questionId",details.getShopId());
                    record.put("userId",order.getUserId());
                    record.put("orderId",order.getId());
                    record.put("orderNo",order.getOrderNo());
                    record.put("detailsId",details.getId());
                    record.put("payType",order.getPayType());
                    record.put("price",details.getRealPrice());
                    record.put("teacherId",details.getShop().getQa().getTeacherId());
                    qaBuyRecordList.add(record);
                });
                qaBuyRecordService.createBuyRecord(qaBuyRecordList);
            }
            if(k.equals(ShopType.ORDER_SHOP_ATTEND)){//旁听
                List<Map<String,Object>> attendBuyRecordList = new ArrayList<>();
                v.forEach(details -> {
                    Map<String,Object> record = new HashMap<>();
                    record.put("questionId",details.getShopId());
                    record.put("userId",order.getUserId());
                    record.put("orderId",order.getId());
                    record.put("orderNo",order.getOrderNo());
                    record.put("detailsId",details.getId());
                    record.put("payType",order.getPayType());
                    record.put("price",details.getRealPrice());
                    record.put("status",1);
                    record.put("teacherId",details.getShop().getQa().getTeacherId());
                    record.put("qaQuestion",details.getShop().getQa());
                    attendBuyRecordList.add(record);
                });
                qaAttendService.addAttend(attendBuyRecordList);
            }
            if(k.equals(ShopType.ORDER_SHOP_BOOK)){
                List<Map<String,Object>> bookList = new ArrayList<>();
                v.forEach(details -> {
                    Map<String,Object> book = new HashMap<>();
                    book.put("id",details.getShopId());
                    book.put("stockNum",details.getBuyNum());
                    book.put("status",0);
                    bookList.add(book);
                });
                bookService.updateStockNum(bookList);
            }
            if(k.equals(ShopType.ORDER_SHOP_ACCOUNT)){//账户充值

                if(order.getPayType().equals(PayType.PAY_TYPE_IOS)){
                    double vmRealPrice = Math.round(order.getRealPrice() * 0.3);
                    double cashRealPrice = order.getRealPrice()-vmRealPrice;
                    cusUserAccountBiz.updateAccountMoney(
                            order.getUserId(),//用户ID
                            vmRealPrice==0?order.getRealPrice():vmRealPrice,//充值金额
                            AccountType.VM.toString(),//充值到课程卡
                            AccountHistoryType.CASHLOAD.getValue(),//现金充值类型
                            order.getId(),//订单ID
                            order.getOrderNo(),//订单号
                            order.getExternalOrderNo(),//第三方订单号
                            true,//显示
                            AccountBizType.CASH.getValue(),//现金充值
                            sysUserId,//管理员ID
                            2,false);
                    if(vmRealPrice>0){
                        cusUserAccountBiz.updateAccountMoney(
                                order.getUserId(),//用户ID
                                cashRealPrice,//充值金额
                                AccountType.CASH.toString(),//现金充值类型
                                AccountHistoryType.CASHLOAD.getValue(),//现金充值类型
                                order.getId(),//订单ID
                                order.getOrderNo(),//订单号
                                order.getExternalOrderNo(),//第三方订单号
                                true,//显示
                                AccountBizType.CASH.getValue(),//现金充值
                                sysUserId,//管理员ID
                                2,true);//进账类型
                    }

                }else{
                    cusUserAccountBiz.updateAccountMoney(
                            order.getUserId(),//用户ID
                            order.getRealPrice(),//充值金额
                            AccountType.CASH.toString(),//现金充值类型
                            AccountHistoryType.CASHLOAD.getValue(),//现金充值类型
                            order.getId(),//订单ID
                            order.getOrderNo(),//订单号
                            order.getExternalOrderNo(),//第三方订单号
                            true,//显示
                            AccountBizType.CASH.getValue(),//现金充值
                            sysUserId,//管理员ID
                            2,false);
                }
            }
        }

        //订单消费金额
        double realPrice = order.getRealPrice().doubleValue();
        //支付成功状态，如果是账户支付且是普通订单类型的，扣除账户中的金额
        if(order.getOrderStatus().equals(OrderStatus.SUCCESS)
                && order.getOrderType().equals(OrderType.COMMON.getKey())
                && realPrice> 0
                && (order.getPayType().equals(PayType.PAY_TYPE_IOS) || order.getPayType().equals(PayType.PAY_TYPE_ACCOUNT)
                || order.getPayType().equals(PayType.PAY_TYPE_ALIPAY) || order.getPayType().equals(PayType.PAY_TYPE_WEIXIN) )){
            if(order.getPayType().equals(PayType.PAY_TYPE_ACCOUNT)){
                //获取用户账户数据
                CusUserAccount userAccount = cusUserAccountBiz.queryUserAccountByUserId(order.getUserId(),false);
                //充值卡金额
                double vmAmount = userAccount.getVmAmount().doubleValue();
                //现金金额
                double cashAmount = userAccount.getCashAmount().doubleValue();
                double subVmAmount = 0D;
                double subCashAmount = 0D;
                if(vmAmount > realPrice ){
                    order.setVmAmount(realPrice);
                    subVmAmount = realPrice;
                }else{
                    realPrice = realPrice - vmAmount;
                    order.setCashAmount(realPrice);
                    subCashAmount = realPrice;
                    subVmAmount = vmAmount;
                    if(vmAmount > 0){
                        order.setVmAmount(vmAmount);
                    }
                }
                if(subVmAmount > 0D){
                    //扣除非现金的金额
                    cusUserAccountBiz.updateAccountMoney(order.getUserId(),subVmAmount,AccountType.VM.toString(),
                            AccountHistoryType.SALES.getValue(),order.getId(),order.getOrderNo(), order.getExternalOrderNo(),
                            true,AccountBizType.SHOP.getValue(),BigDecimal.ZERO,1,false);
                }
                if(subCashAmount > 0D){
                    //扣除现金的金额
                    cusUserAccountBiz.updateAccountMoney(order.getUserId(),subCashAmount,AccountType.CASH.toString(),
                            AccountHistoryType.SALES.getValue(),order.getId(),order.getOrderNo(), order.getExternalOrderNo(),
                            true,AccountBizType.SHOP.getValue(),BigDecimal.ZERO,1,false);
                }
            }else{
                order.setCashAmount(order.getRealPrice());
            }

            //设置推广员收益记录
            this.setAgentIncome(orderDetailsListMaps.get(ShopType.ORDER_SHOP_COURSE),order);
        }
        //支付成功状态，且支付金额大于0的
        if(order.getOrderStatus().equals(OrderStatus.SUCCESS) && realPrice> 0){
            //用户消费任意金额赠送优惠券
            opCouponCodeBiz.giveUserConsumePrice(order.getUserId());
        }
        //支付成功状态，且使用了活动
        if(order.getOrderStatus().equals(OrderStatus.SUCCESS) && DataUtil.idIsNotNull(order.getActivityId())){
            //赠送优惠券活动
            opCouponCodeBiz.giveActivityUserCode(order.getUserId(),order.getActivityId());
            //赠送课程活动
            opActivityBiz.giveFreeCourseActivity(order.getUserId(),order.getActivityId());
        }
        //更新用户附加专业信息
        if(order.getOrderStatus().equals(OrderStatus.SUCCESS) && ObjectUtils.isNotEmpty(courseSubjectIds)){
            cusUserBiz.updateUserAttachSubjectIds(order.getUserId(),courseSubjectIds);
        }
        //发送消息
        if(order.getOrderStatus().equals(OrderStatus.SUCCESS)
                && (order.getPayType().equals(PayType.PAY_TYPE_WEIXIN)
                || order.getPayType().equals(PayType.PAY_TYPE_ACCOUNT)
                || order.getPayType().equals(PayType.PAY_TYPE_ACCOUNT)
                || order.getPayType().equals(PayType.PAY_TYPE_IOS))){
            Map<BigDecimal,List> dataListMap = new HashMap<>();
            dataListMap.put(order.getUserId(),Arrays.asList(order));
            sendMessage.sendMessage(WXTmpEnum.ORDER,Arrays.asList(order.getUserId()),dataListMap);
        }
    }

    /**
     * 设置推广员收益记录
     * @param orderDetailsList 课程类型的流水列表
     * @param order 订单对象
     */
    private void setAgentIncome(List<OrderDetails> orderDetailsList,Order order){
        if(ObjectUtils.isNotEmpty(orderDetailsList)){
            //推广员分成
            Map<Boolean,List<OrderDetails>> _listMap = orderDetailsList.stream().collect(Collectors.groupingBy(e-> StringUtils.isNotEmpty(e.getShareKey())));
            List<Map<String,Object>> agentIncomeInfoList = new ArrayList<>();
            //获取没有推广员KEY的流水列表
            List<OrderDetails> _list = _listMap.get(false);
            if(ObjectUtils.isNotEmpty(_list)){
                //以是否可以分销为条件分组
                Map<Boolean,List<OrderDetails>> _listMap1 = _list.stream().collect(Collectors.groupingBy(e->e.getShop().getCourse().getAllow()==2));
                //获取可以分销的课程
                _list = _listMap1.get(true);
                if(ObjectUtils.isNotEmpty(_list)){
                    BigDecimal userId = _list.get(0).getUserId();
                    //获取流水的用户是否是推广员
                    Map<String,Object> agentUser = agentUserService.findAgentUserByUserId(userId,false,false,false);
                    if(ObjectUtils.isNotEmpty(agentUser)){//如果是推广员，且有父级
                        BigDecimal parentId = new BigDecimal(agentUser.get("parentId").toString());
                        if(DataUtil.idIsNotNull(parentId)){
                            //获取父级推广员
                            Map<String,Object> _agentUser = agentUserService.findAgentUserByUserId(parentId,false,false,false);
                            if(ObjectUtils.isNotEmpty(_agentUser)){//如果父级推广员存在，则给父级分成
                                _list.forEach(e->{
                                    String shareKey = MD5.getMD5(_agentUser.get("userId").toString())+"_"+_agentUser.get("userId");
                                    setData(agentIncomeInfoList,e,order,1,shareKey);
                                });
                            }
                        }
                    }
                }
            }
            //获取有推广员KEY的流水列表
            _list = _listMap.get(true);
            if(ObjectUtils.isNotEmpty(_list)){
                _list.forEach(e->{
                    setData(agentIncomeInfoList,e,order,1,null);
                });
            }
            //执行添加
            if(ObjectUtils.isNotEmpty(agentIncomeInfoList)){
                agentIncomeInfoService.saveAgentIncomeInfo(agentIncomeInfoList);
            }
        }
    }

    /**
     * 设置数据
     * @param agentIncomeInfoList 推广员收益列表
     * @param orderDetails 流水对象
     * @param order 订单对象
     * @param incomeType 收益类型：1.推广收益， 2.奖励金收益
     * @param shareKey 推广员KEY
     */
    private void setData(List<Map<String,Object>> agentIncomeInfoList,OrderDetails orderDetails,Order order,int incomeType,String shareKey){
        Map<String,Object> agentIncomeInfo = new HashMap<>();
        agentIncomeInfo.put("userId",orderDetails.getUserId());
        agentIncomeInfo.put("orderId",orderDetails.getOrderId());
        agentIncomeInfo.put("orderNo",orderDetails.getOrderNo());
        agentIncomeInfo.put("detailsId",orderDetails.getId());
        agentIncomeInfo.put("payTime",order.getPayTime());
        agentIncomeInfo.put("shopData",orderDetails.getShopId()+"-"+orderDetails.getShopType()+"-"+orderDetails.getBuyNum());
        agentIncomeInfo.put("orderPrice",order.getRealPrice());
        agentIncomeInfo.put("shopPrice",orderDetails.getRealPrice());
        agentIncomeInfo.put("incomeType",incomeType);
        if(ObjectUtils.isNotEmpty(shareKey)){
            agentIncomeInfo.put("shareKey",shareKey);
        }else{
            agentIncomeInfo.put("shareKey",orderDetails.getShareKey());
        }
        agentIncomeInfoList.add(agentIncomeInfo);
    }
}
